package com.stackexchange.webapis.methodgroups
{
	import com.adobe.protocols.dict.Response;
	import com.stackexchange.webapis.client.StackExchangeService;
	import com.stackexchange.webapis.events.StackExchangeResultEvent;
	
	import flash.events.EventDispatcher;
	import flash.utils.getQualifiedClassName;

	/**
	 * Base class for all method group
	 */
	public class AbstractMethod extends EventDispatcher
	{
		/** 
		 * A reference to the StackExchangeService that contains the api key
		 * and logic for processing API calls/responses
		 */
		protected var _service:StackExchangeService;
		
		/** 
		 * A reference to the method caller 
		 */
		protected var _methodCaller:MethodCaller;
		
		/** 
		 * A reference to the response parser 
		 */
		protected var _responseParser:ResponseParser;
		
		protected var _className:String;
		
		public function AbstractMethod(service:StackExchangeService, methodCaller:MethodCaller, 
									   responseParser:ResponseParser)
		{
			_service = service;
			_methodCaller = methodCaller;
			_responseParser = responseParser;
			_className = getClassName(this);
		}
		
		/** 
		 * Constructs the query and make the server call
		 */
		protected function call(methodName:String,
								callback:Function,
								tokens:Object,
								parameters:Object=null):void
		{
			_methodCaller.call(_service, _className + "/" + methodName, callback, tokens, parameters);
		}
		
		/**
		 * Parse the result and dispatch an event containing the result
		 */
		protected function processAndDispatch(response:String,
											  responseConstant:String,
											  parseFunction:Function):void
		{
			var event:StackExchangeResultEvent = new StackExchangeResultEvent(responseConstant);
			var result:Object = _responseParser.process(response, parseFunction, _className);
			
			event.success = result.success;
			event.data = result.data;
			
			dispatchEvent(event);
		}
		
		/**
		 * @private
		 * 
		 * return the class name
		 * @param value instance of the class
		 * 
		 **/
		private function getClassName(value:*):String
		{
			var fullClassName:String = getQualifiedClassName(value);
			var i:int = fullClassName.lastIndexOf("::");

			return fullClassName.slice(i + 2).toLowerCase();
		}
	}
}